﻿using ITSparta.MVVM.Services;
using ITSparta.MVVM.Services.Dialogs.FolderBrowse;
using ITSparta.MVVM.Services.Dialogs.OpenFile;
using ITSparta.MVVM.Services.Dialogs.SaveFile;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Threading;

namespace SPConfigDBReaderApp
{
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            ServiceLocator.RegisterSingleton<IClipboardService, ClipboardService>();
            ServiceLocator.RegisterSingleton<IExecuteInUIThreadService, ExecuteInUIThreadService>();
            ServiceLocator.RegisterSingleton<IWindowViewModelMappings, WindowViewModelMappings>();
            ServiceLocator.RegisterSingleton<IDialogService, DialogService>();
            ServiceLocator.RegisterSingleton<ICommandService, CommandService>();
            ServiceLocator.Register<IOpenFileDialog, OpenFileDialogViewModel>();
            ServiceLocator.Register<ISaveFileDialog, SaveFileDialogViewModel>();
            ServiceLocator.Register<IFolderBrowserDialog, FolderBrowserDialogViewModel>();

            ViewModels.MainWindowViewModel.Init();

            var ds = ServiceLocator.Resolve<IDialogService>();
            ds.Show(ViewModels.MainWindowViewModel.Current);
        }

        private void Application_Exit(object sender, ExitEventArgs e)
        {
            ViewModels.MainWindowViewModel.Stop();
        }
    }

    public class WindowViewModelMappings : IWindowViewModelMappings
    {
        private IDictionary<Type, Type> mappings;

        public WindowViewModelMappings()
        {
            mappings = new Dictionary<Type, Type>
            {
                { typeof(ViewModels.MainWindowViewModel), typeof(MainWindow) }
            };
        }

        public Type GetWindowTypeFromViewModelType(Type viewModelType)
        {
            return mappings[viewModelType];
        }
    }

    public interface IExecuteInUIThreadService
    {
        bool CheckAccess();

        void Invoke(Action action);
    }

    public class ExecuteInUIThreadService : IExecuteInUIThreadService
    {
        public bool CheckAccess()
        {
            return Application.Current != null ? Application.Current.Dispatcher.CheckAccess() : false;
        }

        public void Invoke(Action action)
        {
            if (Application.Current != null)
                Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, action);
        }
    }
}